/**
 * 
 */
package com.dianba.commons.utils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.dianba.commons.exception.util.LoggerWapper;

/**
 *
 *
 * @author zhoucong
 * @date 2016年5月2日 下午3:09:25
 */
public class BeanUtil {
	private static LoggerWapper log = new LoggerWapper(BeanUtil.class);

	/**
	 * 对象转 Map
	 *
	 * @param obj
	 * @return
	 * @author zhoucong
	 * @date 2016年5月4日 上午9:21:34
	 */
	@SuppressWarnings("unchecked")
	public static <E extends Map<?, ?>> E toMapByDeclaredFields(Object obj) {
		if (obj == null) {
			return null;
		}
		Map<Object, Object> map = new HashMap<>();
		Field[] fields = obj.getClass().getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				map.put(field.getName(), field.get(obj));
			} catch (IllegalArgumentException | IllegalAccessException e) {
				log.debug("toMap failed in fieldName : " + field.getName(), e);
			}
		}

		return (E) map;
	}

	/**
	 * 对象转 Map , 如果有从复的属性则后面的覆盖前面的
	 *
	 * @param obj
	 *            需要转换的对象
	 * @param keyField
	 *            字段的值作为 KEY
	 * @param valueField
	 *            字段的值作为 value
	 * @return
	 * @author zhoucong
	 * @date 2016年5月4日 上午9:21:51
	 */
	@SuppressWarnings("unchecked")
	public static <E extends Map<?, ?>> E toMapByDeclaredFieldValue(Collection<?> objs, String keyField,
			String valueField) {
		if (objs == null) {
			return null;
		}
		Map<Object, Object> map = new HashMap<>();
		for (Object obj : objs) {

			Field[] fields = obj.getClass().getDeclaredFields();
			Object key = "";
			Object value = null;
			for (Field field : fields) {
				field.setAccessible(true);
				try {
					if (field.getName().equals(keyField)) {
						key = field.get(obj);
					}
					if (field.getName().equals(valueField)) {
						value = field.get(obj);
					}

				} catch (IllegalArgumentException | IllegalAccessException e) {
					log.debug("toMap failed in fieldName : " + field.getName(), e);
				}
			}
			map.put(key, value);
		}
		return (E) map;
	}

	public <E extends Map<?, ?>> E toMap(List<Map<String, Object>> sources, String pk) {
		Map<Object, Map<String, Object>> linkedMap = new LinkedHashMap<>();
		for (Map<String, Object> map : sources) {
			linkedMap.put(map.get(pk), map);
		}
		return (E) linkedMap;
	}

	public void unionMap(List<Map<String, Object>> sources, List<Map<String, Object>> targets, String pk, String fk,
			String... keys) {
		boolean isUnionAll = keys == null || keys.length == 0;
		Map<Object, Map<String, Object>> lmap = toMap(sources, pk);
		for (Map<String, Object> target : targets) {
			Map<String, Object> source = lmap.get(target.get(fk));
			if (source == null) {
				if (isUnionAll) {
					for (String key : keys) {
						target.put(key, null);
					}
				}
				continue;
			}
			if (isUnionAll) {
				target.putAll(source);
			} else {
				for (String key : keys) {
					target.put(key, source.get(key));
				}
			}

		}
	}
}
